package com.irdstudio.apicenter.gateway.comm;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.irdstudio.apicenter.gateway.core.dm.AppTradeInout;

/**
 * MACCS 通讯包组包辅助类
 * @author 李广明
 * @version 1.1
 * @date 2015-05-24
 */
public class MaccsPacketUtil {
	
	/* 数据包中的代码标识-失败 */
	public final static String FAILURE_FLAG = "999";
	/* 数据包中的代码标识-成功 */
	public final static String SUCCESS_FLAG = "000";
	
	/**
	 * 创建标准的数据包,错误码不需要定义，只需传入错误信息
	 * @param errCode
	 * @param errMsg
	 * @return
	 */
	public static MaccsPacket makeFailurePacket(String errMsg) {
		MaccsPacket packet = new MaccsPacket();
		packet.addVariable("returnCode", FAILURE_FLAG);
		packet.addVariable("returnMsg", errMsg);
		return packet;
	}
	
	/**
	 * 创建一个标准的成功信息数据包
	 * @return
	 */
	public static MaccsPacket makeSuccessPacket() {
		MaccsPacket packet = new MaccsPacket();
		packet.addVariable("ec", SUCCESS_FLAG);
		packet.addVariable("em", "OK!");
		return packet;
	}	
	
	/**
	 * 创建自定义的错误信息包
	 * @param errCode
	 * @param errMsg
	 * @return
	 */
	public static MaccsPacket makeCustomFailurePacket(String errCode,String errMsg){
		MaccsPacket packet = new MaccsPacket();
		packet.addVariable("ec", errCode);
		packet.addVariable("em", errMsg);
		return packet;		
	}

	/**
	 * 创建 一个简单的成功信息包
	 * 包含成功数据代码与数据信息
	 * @param successMsg
	 * @return
	 */
	public static MaccsPacket makeSimpleSuccessPacket(String successMsg) {
		MaccsPacket packet = new MaccsPacket();
		packet.addVariable("returnCode", SUCCESS_FLAG);
		packet.addVariable("returnMsg", successMsg);
		return packet;
	}
	
	/**
	 * 制作成定长报文格式的字符串
	 * @param packet
	 * @return
	 */
	public static String makeFixedString(MaccsPacket packet) {
		StringBuffer sb = new StringBuffer("");
		for (Iterator<?> iter = packet.getMap().keySet().iterator(); iter
				.hasNext();) {
			String f = (String) iter.next();
			sb.append(f).append("=").append(packet.getValue(f)).append("&");
		}
		if (sb.length() > 0)
			sb.deleteCharAt(sb.length() - 1);
		return sb.toString();
	}

	/**
	 * 按指定配置格式组合发送字符串
	 * @param list
	 * @param inUvo
	 * @return
	 */
	public static String makeFormatString(List<AppTradeInout> inList,
			MaccsPacket inUvo) {
		StringBuffer sb = new StringBuffer("");
		for (AppTradeInout inout : inList) {
			sb.append(inout.getTradeElementCode()).append("=").append(
					MaccsFormatUtil.format(inUvo,inout)).append("&");
		}
		if (sb.length() > 0)
			sb.deleteCharAt(sb.length() - 1);
		return sb.toString();
	}

	/**
	 * 按指定的配置格式返回重组合的包
	 * @param backPacket
	 * @return
	 */
	public static MaccsPacket makeFormatPacket(final List<AppTradeInout> inoutList,
			final MaccsPacket srcPacket) {
		MaccsPacket targetPacket = new MaccsPacket();
		for (AppTradeInout inout : inoutList) {
			
			// 取源数据包中取得原值对象
			Object vo = srcPacket.getObject(inout.getTradeElementCode());
			
			// 判断源值对象类型,并根据类型决定如何组装返回包
			if(vo != null && vo instanceof ArrayList<?>) {
				
				// 如果为数组,则直接在返回包中增加一个空的数组对象
				List<Object> subList = new ArrayList<Object>();
				
				// 递归取值
				makeSubListPacket((ArrayList<?>) vo,subList,inout.getTradeElementCode(),inoutList);
				
				// 将取回的值加入到返回包中
				targetPacket.addVariable(inout.getTradeElementCode(), subList);
			} else if(vo != null && vo instanceof HashMap<?, ?> ){
				
				// 如果为map，则直接在返回包中增加一个空的Map
				Map<String, Object> subMap = new HashMap<String, Object>();	
				
				// 直接取下级的值
				makeSubMapPacket((HashMap<?, ?>)vo,subMap,inout.getTradeElementCode(),inoutList);
				
				// 将取回的值加入到返回包中
				targetPacket.addVariable(inout.getTradeElementCode(), subMap);
			} else {
				
				// 如果有上级交易元素代码,则说明也不应该在此处进行格式化
				if (StringUtils.isEmpty(inout.getTradeAbvElementCode())) {
					// 说明为普通键值对象,直接进行格式化
					targetPacket.addVariable(inout.getTradeElementCode(),
							MaccsFormatUtil.format(srcPacket, inout));
				}
			}
		}
		return targetPacket;
	}

	/**
	 * 组装下级数据（非明细，下级MAP）
	 * @param vo
	 * @param subMap
	 * @param tradeElementCode
	 * @param inoutList
	 */
	private static void makeSubMapPacket(HashMap vo, Map<String, Object> subMap,
			String tradeAbvElementCode, List<AppTradeInout> inoutList) {
		
		MaccsPacket subSrcPacket = new MaccsPacket(vo);
		MaccsPacket subTargetPacket = new MaccsPacket(subMap);
		boolean isConfFlag = false;
		for (AppTradeInout inout : inoutList) {
			if (inout.getTradeAbvElementCode().equals(tradeAbvElementCode)) {
				isConfFlag = true;
				subTargetPacket.addVariable(inout.getTradeElementCode(),
						MaccsFormatUtil.format(subSrcPacket, inout));			
			}
		}
		// 如果没有配置,则直接原样复制过来
		if(!isConfFlag){
			subMap = vo;
		}
	}

	/**
	 * 递归组装下级明细列表数据
	 * @param vo 
	 * @param subList
	 * @param tradeAbvElementCode
	 * @param inoutList
	 */
	private static void makeSubListPacket(ArrayList<?> srcValueList, List<Object> subList,
			String tradeAbvElementCode, List<AppTradeInout> inoutList) {
		
		// 将源值下所有记录遍历,为每条记录进行格式化
		for(Object srcObject : srcValueList){
			
			MaccsPacket subSrcPacket = new MaccsPacket((Map<String, Object>)srcObject);
			MaccsPacket subTargetPacket = new MaccsPacket();
			// 遍历配置，如果上级交易元素代码等于传入的上级交易元素代码,说明为下级列表,进行组装
			for (AppTradeInout inout : inoutList) {
				if (inout.getTradeAbvElementCode().equals(tradeAbvElementCode)) {
					
					Object vo = subSrcPacket.getObject(inout.getTradeElementCode());
					if(vo != null && vo instanceof ArrayList<?>) {
						List<Object> deepList = new ArrayList<Object>();
						makeSubListPacket((ArrayList<?>) vo,deepList,inout.getTradeElementCode(),inoutList);
					} else {
						subTargetPacket.addVariable(inout.getTradeElementCode(),
								MaccsFormatUtil.format(subSrcPacket, inout));						
					}
				}				
			}
			// 将结果Map放入到结果List中
			subList.add(subTargetPacket.getMap());			
		}		
	}



	
}
